"""数据存储接口"""

from typing import Optional
from .sqlite_storage import SQLiteStorage
import uuid
from dataclasses import dataclass,field
from models.entities import *
import simpy
import json



class DBManager:
    """ 数据库管理器，统一管理所有数据库操作 """
    _instance:Optional['DBManager']=None
    batch_goods_queue=[]
    batch_vehicle_queue=[]
    batch_status_queue=[]
    batch_size:int=100
    _initialized:bool=False

    def __new__(cls,db_path:str="./warehouse.db"):
        """ 单例模式 确保只有一个数据库连接 """
        if cls._instance is None:
            cls._instance=super(DBManager,cls).__new__(cls)
            cls._instance._initialized=False
        return cls._instance

    def  __init__(self,db_path:str="./warehouse.db"):
        """ 初始化数据库连接 """
        if self._initialized:
            return
        self.db:SQLiteStorage=SQLiteStorage(db_path)
        self.banch_goods_queue=[]
        self.banch_vehicle_queue=[]
        self.banch_order_queue=[]
        # 定义一个标志 标识已经初始化过了
        self._initialized=True

    def close(self)->None:
        """ 关闭数据库连接 """
        if hasattr(self,"db") and self.db:
            self.db.close()

    def __del__(self)->None:
        """ 析构函数 ，确保数据库连接被关闭"""
        self.force_flush_batch()
        self.close()
    
    # 提供一个统一的初始化方法
    @staticmethod
    def initialize(db_path:str="./warehouse.db")->Optional['DBManager']:
        """ 
        初始化数据库管理器
        """
        try:
            instance:DBManager=DBManager(db_path)
            if instance and instance._initialized:
                pass
            else:
                print("数据库初始化失败")
            return instance
        except Exception as e:
            print(f"初始化数据库管理器失败:{e}")
            return None
        

    def insert_goods(self,goods:Goods,time:float)->bool:
        """ 插入商品信息 """
        query="insert into goods(id,type,infos,create_time) values(?,?,?,?)"
        params=(goods.id,goods.type,json.dumps(goods.infos),time)
        return self.db.excute_insert(query,params) is not None

    def insert_goods_b(self,goods:Goods,time:float)->None:
        """ banch 插入商品信息 """
        self.batch_goods_queue.append({"goods":goods,"time":time})
        if len(self.batch_goods_queue)>self.batch_size:
            self._flush_batch_goods()

    def _flush_batch_goods(self)->None:
        """ 批量插入商品信息 """
        query="insert into goods(id,type,infos,create_time) values(?,?,?,?)"
        values  =[]
        for goods_item in self.batch_goods_queue:
            params=(goods_item["goods"].id,goods_item["goods"].type,json.dumps(goods_item["goods"].infos),goods_item["time"])
            values.append(params)
        self.db.excute_insert_batch(query,values)
        self.batch_goods_queue.clear()

    def insert_vehicle(self,vehicle:Vehicle,time:float)->bool:
        query="""
        insert into vehicle (id,type,infos,create_time) values (?,?,?,?)
        """
        params=(vehicle.id,vehicle.type,json.dumps(vehicle.infos),time)
        return self.db.excute_insert(query,params) is not None

    def insert_vehicle_b(self,vehicle:Vehicle,time:float)->None:
        """ 批量插入车辆信息"""
        self.batch_vehicle_queue.append({"vehicle":vehicle,"time":time})
        if len(self.batch_vehicle_queue)>self.batch_size:
            self._flush_batch_vehicle()
    def _flush_batch_vehicle(self)->None:
        """ 批量插入车辆信息 """
        query="INSERT INTO vehicle(id,type,infos,create_time) VALUES(?,?,?,?)"
        values=[]
        for vehicle in self.batch_vehicle_queue:
            params=(vehicle["vehicle"].id,vehicle["vehicle"].type,json.dumps(vehicle["vehicle"].infos),vehicle["time"])
            values.append(params)
        self.db.excute_insert_batch(query,values)
        self.batch_vehicle_queue.clear()
    
    def insert_status(self,id:str, type:str,status:str,time:float)->bool:
        query="""
        insert into status (id,type,status,create_time) values (?,?,?,?)
        """
        params=(id,type,status,time)
        return self.db.excute_insert(query,params) is not None

    def insert_status_b(self,id:str, type:str,status:str,time:float)->None:
        """ 批量插入状态 """
        self.batch_status_queue.append({"id": id,"type":type,"status":status,"time":time})
        if len(self.batch_status_queue)>=self.batch_size:
            self._flush_batch_status()
    
    def _flush_batch_status(self)->None:

        query="INSERT INTO status(obj_id,type,status,create_time) VALUES(?,?,?,?)"
        values=[]
        for status in self.batch_status_queue:
            params=(status["id"],status["type"],status["status"],status["time"])
            values.append(params)
            #print(f"{status["id"]} {status["time"]} 添加状态 {status}")
        self.db.excute_insert_batch(query,values)
        self.batch_status_queue.clear()


    def force_flush_batch(self)->None:
        self._flush_batch_goods()
        self._flush_batch_vehicle()
        self._flush_batch_status()
    
    def clear_dbdata(self)->None:
        self.db.clear()
        
        


def clear_dbdata()->None:
    """ 清空数据库数据 """
    dbm=DBManager.initialize()
    if dbm is None: return 
    dbm.clear_dbdata()

def force_flush_batch()->None:
    """ 强制刷新批次数据 """
    dbm=DBManager.initialize()
    if dbm is None: return 
    dbm.force_flush_batch()


def generate_id(prefix:str="",len:int=8)->str:
    """ 生成随机id"""
    return f"{prefix}-{uuid.uuid4().hex[:len]}"

def insert_goods(goods:Goods,env :simpy.Environment)->bool:
    """ 插入单条商品信息 """
    dbm=DBManager.initialize()
    if dbm is None: return False
    return dbm.insert_goods(goods,env.now)

def insert_goods_b(goods:Goods,env :simpy.Environment)->None:
    dbm=DBManager.initialize()
    if dbm is not None: 
        dbm.insert_goods_b(goods,env.now)

def insert_vehicle(vehicle:Vehicle,env :simpy.Environment)->bool:
    """ 插入单条车辆信息 """
    dbm=DBManager.initialize()
    if dbm is None: return False
    return dbm.insert_vehicle(vehicle,env.now)

def insert_vehicle_b(vehicle:Vehicle,env :simpy.Environment)->None:
    """ 插入车辆信息 """
    dbm=DBManager.initialize()
    if dbm is None: return
    dbm.insert_vehicle_b(vehicle,env.now)

def insert_status(id:str, type:str,status:str,env :simpy.Environment)->None:
    """ 插入单条变化状态 """
    dbm=DBManager.initialize()
    if dbm is None: return
    dbm.insert_status(id,type,status,env.now)
def insert_status_b(id:str, type:str,status:str,env :simpy.Environment)->None:
    """ 插入变化状态 """
    dbm=DBManager.initialize()
    if dbm is None: return
    dbm.insert_status_b(id,type,status,env.now)



     



